<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
import { chengduOldPolygon } from 'src/utils/chengdu'
import MiniMapViewer from 'src/components/mini-map.vue'
import { getQuerySet } from 'src/utils/request.js'

let map
let loca
let defaultLayer
let oldMapLayer
let jinheLine
let buildingPolygon
let timeout

const isMobile = window.matchMedia('(pointer:coarse)').matches
const showToggleList = ref(!isMobile)
const showMap = ref(true)
const showOldMap = ref(true)
const showJinhe = ref(true)
const showBuilding = ref(true)
const currentMarker = ref(null)
const oldMaps = ref(null) // 点击弹出的古旧地图列表

defineEmits(['openImage'])
onMounted(() => {
  initMap()
})
onBeforeUnmount(() => {
  clearTimeout(timeout)
  map.destroy()
  loca.destroy()
  map = null
  loca = null
})

function initMap () {
  defaultLayer = AMap.createDefaultLayer({
    rejectMapMask: true
  })
  map = new AMap.Map('map', {
    center: [104.065743, 30.657462],
    zoom: 15,
    viewMode: '3D',
    pitch: 0,
    resizeEnable: true,
    rotateEnable: true,
    pitchEnable: true,
    mapStyle: 'amap://styles/a3891ab2c2a22987e441b1d6ec99feb4',
    mask: chengduOldPolygon,
    layers: [defaultLayer]
  })
  loca = new Loca.Container({ map })
  loca.ambLight = {
    intensity: 2.2,
    color: '#babedc'
  }
  loca.dirLight = {
    intensity: 0.46,
    color: '#d4d4d4',
    target: [0, 0, 0],
    position: [0, -1, 1]
  }
  loca.pointLight = {
    color: '#FFCC33',
    position: [104.065743, 30.657462, 2600],
    intensity: 18,
    // 距离表示从光源到光照强度为 0 的位置，0 就是光不会消失。
    distance: 3900
  }
  // 成都街市图
  oldMapLayer = new AMap.TileLayer({
    getTileUrl: 'https://media.ditushu.com/demo/sdht/maptiles/[z]/[x]/[y].jpg',
    zIndex: 3,
    zooms: [12, 17],
    opacity: 0.8,
    rejectMapMask: false
  })
  oldMapLayer.setMap(map)
  // 建筑物模型
  buildingPolygon = new Loca.PolygonLayer({
    zIndex: 120,
    shininess: 10,
    hasSide: true,
    cullface: 'back',
    depth: true,
    zooms: [13, 15]
  })
  const build = new Loca.GeoJSONSource({
    url: 'https://media.ditushu.com/demo/sdht/chengdu_build.geojson'
  })
  buildingPolygon.setSource(build)
  buildingPolygon.setStyle({
    topColor: '#1f5354',
    sideColor: '#1976D2',
    sideTopColor: '#1976D2',
    sideBottomColor: '#1f5354',
    height: function (index, feature) {
      return feature.properties.Floor * 6
    }
    // textureSize: [1000, 820],
    // texture: 'https://a.amap.com/Loca/static/loca-v2/demos/images/windows.jpg',
  })
  buildingPolygon.setLoca(loca)
  // 金河
  const jinhe = new Loca.GeoJSONSource({
    url: 'https://media.ditushu.com/demo/sdht/jinhe.geojson'
  })
  jinheLine = new Loca.LineLayer({ loca })
  jinheLine.setSource(jinhe, {
    color: '#ffff00',
    lineWidth: 6,
    altitude: 100
    // dashArray: [10, 5, 10, 0],
  })
  loca.add(jinheLine)
  // 地标点
  getQuerySet({
    api: 'https://api.ditushu.com/book/52/storage/draft/landmark/',
    limit: 1000
  }).then(({ status, data }) => {
    if (status !== 200 || !data.results.length) {
      return
    }
    const markers = {
      type: 'FeatureCollection',
      features: data.results.filter(item => item.geometry).map(item => ({
        type: 'Feature',
        properties: {
          id: item._id,
          name: item.title
        },
        geometry: item.geometry
      }))
    }
    const points = new Loca.GeoJSONSource({ data: markers })
    const breathRed = new Loca.ScatterLayer({
      loca,
      zIndex: 121,
      opacity: 1,
      visible: true,
      zooms: [2, 22]
    })
    breathRed.setSource(points)
    breathRed.setStyle({
      size: [60, 60],
      borderWidth: 0,
      texture: 'https://a.amap.com/Loca/static/loca-v2/demos/images/breath_red.png',
      duration: 500,
      animate: true
    })
    loca.add(breathRed)
    // 绑定地标点事件
    markers.features.forEach(point => {
      const marker = new AMap.Marker({
        position: new AMap.LngLat(...point.geometry.coordinates),
        content: '<div style="height: 40px; width: 40px"></div>',
        title: point.properties.name || '地标点',
        anchor: 'center'
      })
      map.add(marker)
      marker.on('click', async () => {
        const { status, data } = await getQuerySet({
          api: 'https://api.ditushu.com/book/52/storage/draft/mark/',
          limit: 1000,
          params: {
            filter: 'lanmark:' + point.properties.id
          }
        })
        if (status !== 200 || !data.results.length) {
          return
        }
        oldMaps.value = data.results.slice(0, isMobile ? 8 : 12).map(item => {
          const map = item.map
          map.id = map._id
          map.coordinate = item.coordinate
          return item.map
        })
        currentMarker.value = point.properties
      })
    })
  })
  // 动画
  loca.animate.start()
  map.on('complete', () => {
    setTimeout(() => {
      loca.viewControl.addAnimates([{
        pitch: {
          value: 45,
          control: [[0.3, 0], [0.4, 45]],
          timing: [0, 0, 1, 1],
          duration: 2000
        }
      }])
    }, 1000)
  })
}
function toggleElement (type, value) {
  const layer = {
    map: defaultLayer,
    oldmap: oldMapLayer,
    jinhe: jinheLine,
    building: buildingPolygon
  }[type]
  value ? layer.show() : layer.hide()
}
</script>

<template>
  <div class="map-title absolute">
    <span class="text-yellow-2">历史地名</span>
  </div>
  <div class="map-toggle-list absolute">
    <div v-if="showToggleList" class="toggle-box q-py-xs q-pr-md">
      <div><q-toggle v-model="showMap" @update:model-value="value => toggleElement('map', value)" /> 现代地图</div>
      <div><q-toggle v-model="showOldMap" @update:model-value="value => toggleElement('oldmap', value)" /> 成都街市图</div>
      <div><q-toggle v-model="showJinhe" @update:model-value="value => toggleElement('jinhe', value)" /> 金河</div>
      <div><q-toggle v-model="showBuilding" @update:model-value="value => toggleElement('building', value)" /> 建筑物模型</div>
    </div>
    <q-btn v-if="isMobile" dense icon="menu" color="white" text-color="black" @click="showToggleList = !showToggleList" />
  </div>
  <div id="map" class="absolute-full" />
  <transition name="slide-box">
    <div v-if="currentMarker" class="absolute-full row overflow-hidden" style="z-index: 2">
      <div v-for="n of 2" :key="n" class="absolute-full bg-amber-1 overflow-hidden" :class="n === 1 ? 'slide-left' : 'slide-right'">
        <div class="row flex-center absolute" style="width: 100vw" :style="n === 1 ? 'left: 0' : 'right: 0'">
          <div class="col-lg-8 col-12 q-px-md q-py-xl">
            <div class="q-mx-lg q-mb-md row" style="font-size: 2em; color:#1f5354">
              <div>{{ currentMarker.name }}</div>
              <q-space />
              <q-btn dense flat icon="close" color="black" @click="currentMarker = null">
                <q-tooltip content-class="size-14">返回地图</q-tooltip>
              </q-btn>
            </div>
            <div class="row relative-position">
              <div v-for="(oldMap, i) of oldMaps" :key="i" class="col-lg-3 col-6 q-px-lg q-py-md cursor-pointer" @click="$emit('openImage', oldMap)">
                <q-responsive :ratio="16/10">
                  <mini-map-viewer :image="oldMap" />
                </q-responsive>
                <div class="text-teal-10 q-pt-sm text-center" :style="{ fontSize: isMobile ? '14px' : '17px' }">{{ oldMap.title }}</div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </transition>
</template>

<style lang="scss">
.map-title {
  z-index: 1;
  left: calc(50% - 6em);
  top: 50px;
  span {
    font-size: 3em;
    line-height: 1;
    font-family: SourceHanSerifCN-Heavy, serif;
    text-shadow: 1px 1px #000;
  }
}
.map-toggle-list {
  z-index: 2;
  left: 2em;
  bottom: 2em;
  .toggle-box {
    background: rgba(255,255,255,.9);
    border-radius: 3px;
  }
}
#map {
  .amap-logo, .amap-copyright {
    display: none!important;
  }
}
.slide-left {
  right: 50%;
}
.slide-right {
  left: 50%;
}
.slide-box-enter-active, .slide-box-leave-active {
  transition: all .8s ease-out;
  .slide-left, .slide-right {
    transition: transform .8s ease-out;
  }
}
.slide-box-enter-from, .slide-box-leave-to {
  .slide-left {
    transform: translateX(-100%)
  }
  .slide-right {
    transform: translateX(100%)
  }
}
</style>
